<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    #div1{width:780px;height:400px;background:url(./00.jpg) no-repeat; margin: 20px auto; overflow: hidden;}
    body{background:black;margin:0;}
  </style>
</head>
<body>
<div id="div1">
</div>
<script>
  window.onload = function () {
    //NS → namespace

    const svgNS = 'http://www.w3.org/2000/svg';
    const oParent = document.getElementById('div1');
    const centerX = oParent.offsetWidth / 2;
    const centerY = oParent.offsetHeight / 2;

    const circleNum = 9;
    const centerR = 150;
    const otherData = [];

    for (let i = 0; i < circleNum; ++i) {
      const y = Math.sin(i * 40 * Math.PI / 180) * centerR + centerY;
      const x = Math.cos(i * 40 * Math.PI / 180) * centerR + centerX;
      otherData.push({x:x,y:y, text: i})
    }

    const data = {
      centerNode: {text: "鲁路修"},
      otherNode: otherData
    };

    function createTag(tag, objAttr){
      const oTag = document.createElementNS(svgNS, tag);
      for(let attr in objAttr){
        oTag.setAttribute(attr, objAttr[attr]);
      }
      return oTag;
    }

    function addTag(){
      const oSvg = createTag('svg', {xmlns: svgNS, width: "100%", height: "100%"});

      for(let i=0;i<data.otherNode.length;++i){
        addOtherTag(data.otherNode[i], oSvg);
      }

      const oG = createTag("g", {style: "cursor:pointer"});
      const oCircle = createTag('circle',{cx:centerX,cy:centerY, r: 40, fill: "white", stroke: "red", "stroke-width":1});
      const oText = createTag('text',{x:centerX, y: centerY + 8, 'font-size':20, 'text-anchor':'middle'})
      oText.innerHTML = data.centerNode.text;
      oG.appendChild(oCircle);
      oG.appendChild(oText);
      oSvg.appendChild(oG);
      oParent.appendChild(oSvg)
    }

    function addOtherTag(otherAttr, oSvg){
      /* 线 */
      let oG = createTag("g", {style: "cursor:pointer", class:'lineStyle'});
      const oLine1 = createTag("line", {x1: otherAttr.x, y1: otherAttr.y, x2: centerX, y2: centerY, stroke: "#ccc"});
      const oLine2 = createTag("line", {x1: otherAttr.x, y1: otherAttr.y, x2: centerX, y2: centerY, stroke: "transparent",
        "stroke-width": 10});
      const oRect = createTag("rect",{x: (otherAttr.x + centerX) / 2 - 10,y:(otherAttr.y + centerY) / 2 - 10,fill:"#999",width:20,height:20,rx:5});
      let oText = createTag("text",{x:(otherAttr.x + centerX) / 2,y:(otherAttr.y + centerY) / 2 + 8,fill:"white","font-size":20,"text-anchor":"middle"});
      oText.innerHTML = "?";
      oG.appendChild(oLine1);
      oG.appendChild(oLine2);
      oG.appendChild(oRect);
      oG.appendChild(oText);
      oSvg.appendChild(oG)

      /* 圆 */
      oG = createTag("g", {style: "cursor:pointer", class: 'circleStyle'});
      const oCircle = createTag('circle', {
        cx: otherAttr.x,
        cy: otherAttr.y,
        r: 30,
        fill: 'white',
        stroke: 'red',
        'stoke-width': 1
      });
      oText = createTag('text', {
        x: otherAttr.x,
        y: otherAttr.y + 8,
        'font-size': 20,
        'text-anchor': 'middle'
      });
      oText.innerHTML = otherAttr.text;
      oG.appendChild(oCircle);
      oG.appendChild(oText);

      oSvg.appendChild(oG);
    }

    function bindTag(){
      const aLine = document.getElementsByClassName('lineStyle');
      const aCircle = document.getElementsByClassName('circleStyle');

      for(let i=0;i<aCircle.length;++i){
        aCircle[i].onmouseenter = function () {
          startMove(this.getElementsByTagName('circle')[0],30,40);
          const prevLine = this.previousElementSibling;
          prevLine.getElementsByTagName('line')[0].setAttribute('stroke', 'blue');
          prevLine.getElementsByTagName('rect')[0].setAttribute('fill', 'red');
        };
        aCircle[i].onmouseleave = function () {
          startMove(this.getElementsByTagName('circle')[0],30,40);
          const prevLine = this.previousElementSibling;
          prevLine.getElementsByTagName('line')[0].setAttribute('stroke', '#ccc');
          prevLine.getElementsByTagName('rect')[0].setAttribute('fill', '#999');
        };
      }

      for(let i=0;i<aLine.length;++i){
        aLine[i].onmouseenter = function () {
          this.getElementsByTagName('line')[0].setAttribute('stroke', 'blue');
          this.getElementsByTagName('rect')[0].setAttribute('fill', 'red');
          const prevCircle = this.nextElementSibling;
          startMove(prevCircle.getElementsByTagName('circle')[0],30,40);
        };
        aLine[i].onmouseleave = function () {
          this.getElementsByTagName('line')[0].setAttribute('stroke', '#ccc');
          this.getElementsByTagName('rect')[0].setAttribute('fill', '#999');
          const prevCircle = this.nextElementSibling;
          startMove(prevCircle.getElementsByTagName('circle')[0],30,40);
        };
      }
    }

    function startMove(obj,r1,r2) {
      let nowR = r1;
      const overR = r2;
      obj.speed = 0;
      clearInterval(obj.timer);
      obj.timer = setInterval(function(){
        obj.speed += (overR - nowR) / 6;
        obj.speed *= 0.9;
        if (Math.abs(overR - nowR) <= 1 && Math.abs(obj.speed) <= 1) {
          clearInterval(obj.timer);
          obj.setAttribute('r', overR);
        }else {
          nowR += obj.speed;
          obj.setAttribute('r', nowR);
        }
      },30)
    }

    addTag();

    bindTag();

  };
</script>
</body>
</html>
